//
//  XIParticle.h
//  XIEngine
//
//  Created by Balazs Faludi on 07.01.10.
//  Copyright 2010 Universität Basel. All rights reserved.
//


#import <OpenGLES/EAGL.h>
#import <OpenGLES/ES1/gl.h>
#import <OpenGLES/ES1/glext.h>
//#import "XIPaint.h"
#import "XIEngine.h"

#define kNumParticles 10000
#define kInitialParticleSpread 100
#define kSpeedDecay 0.00005f

typedef enum {
	XIParticleEmiterBlendNone, XIParticleEmiterBlendAdd, XIParticleEmiterBlendMult, XIParticleEmiterBlendInterpolate
} XIParticleEmiterBlendMode;

typedef enum XIParticleEmiterRenderMode {
	XIParticleEmiterRenderAllAtOnce, XIParticleEmiterRenderSeparate
} XIParticleEmiterRenderMode;

typedef enum XIParticleEmiterType {
	XIParticleEmiterTypeSprite, XIParticleEmiterTypePoint, XIParticleEmiterTypeLine
} XIParticleEmiterType;

typedef struct XIParticle {
	XIVec   pos, vec, acc; // Current position, speed and acceleration of the particle.
	XIPaint color;
	XIFloat age;
	XIFloat life;
	XIFloat size, growth;
	XIFloat angle, rot, rotAcc;	// Current angle, rotation speed and rotation acceleration.
	struct XIParticle *child;
	struct XIParticleEmiter *emiter;
	int     phase;
	BOOL    killed;
	void   *data;   // User-defineable data pointer.
} XIParticle;

typedef struct XIParticleNode {
	XIParticle *value;
	struct XIParticleNode *next;
	struct XIParticleNode *prev;
} XIParticleNode;

typedef struct {
	XIParticleNode *head;
	XIParticleNode *tail;
	int count;
	int maxNodes;
} XIParticleStack;

typedef struct XIParticleEmiter {
	XIVec   pos;
	XIParticleStack *particles;
	BOOL    active;
	XIFloat age;
	GLuint  texture;
	XIFloat lastEmit;
	XIFloat emitInterval;
	int     emitAmount;
	void  (*stepFunction)(XIParticle *);
	void  (*initFunction)(XIParticle *);
	int      capacity;
	GLfloat *vertices;
	GLfloat *texCoords;
	GLfloat *colors;
	XIParticleEmiterBlendMode  blendMode;
	XIParticleEmiterRenderMode renderMode;
	XIParticleEmiterType type;
} XIParticleEmiter;

extern XIParticle * XIParticleCreate();
extern void XIParticleRelease(XIParticle *p);

extern XIParticleStack * XIParticleStackCreate();
extern BOOL XIParticlePush(XIParticleStack *stack, XIParticle *particle);
extern BOOL XIParticlePop(XIParticleStack *stack, XIParticle **particle);
extern void XIParticleStackRelease(XIParticleStack *stack);

extern XIParticleEmiter * XIParticleEmiterCreate(int capacity);
extern void XIParticleEmiterRelease(XIParticleEmiter *emiter);
extern void XIParticleEmiterStart(XIParticleEmiter *emiter);
extern void XIParticleEmiterStop(XIParticleEmiter *emiter);
extern void XIParticleEmiterEmit(XIParticleEmiter *emiter);
void XIParticleEmiterAddParticle(XIParticleEmiter *emiter, XIParticle *newParticle);
extern void XIParticleEmiterStep(XIParticleEmiter *emiter);
extern BOOL XIParticleEmiterRender(XIParticleEmiter *emiter);
extern void XIParticleEmiterDefaultInitFunction(XIParticle *p);
extern void XIParticleEmiterDefaultStepFunction(XIParticle *p);